package com.wiscamp.ninechapters.problems.application.assemblers;

import com.wiscamp.ninechapters.problems.application.dto.commands.problems.*;
import com.wiscamp.ninechapters.problems.application.dto.vo.problems.*;
import com.wiscamp.ninechapters.problems.domain.models.problems.answers.Answer;
import com.wiscamp.ninechapters.problems.domain.models.problems.problems.Problem;
import com.wiscamp.ninechapters.problems.domain.models.problems.problems.ProblemKnowledgePoint;
import com.wiscamp.ninechapters.problems.domain.models.problems.problems.Stem;
import com.wiscamp.ninechapters.problems.domain.models.problems.questions.Option;
import com.wiscamp.ninechapters.problems.domain.models.problems.questions.Question;
import com.wiscamp.ninechapters.problems.domain.models.problems.questions.Solution;
import com.wiscamp.ninechapters.tags.application.dto.vo.KnowledgePointVO;
import com.wiscamp.ninechapters.tags.application.dto.vo.TagNameVO;
import com.wiscamp.ninechapters.tags.application.dto.vo.TagVO;
import com.wiscamp.ninechapters.tags.domain.models.TagName;
import org.mapstruct.Mapper;
import org.mapstruct.Mapping;
import org.mapstruct.NullValuePropertyMappingStrategy;
import org.mapstruct.ReportingPolicy;
import org.mapstruct.factory.Mappers;

@Mapper(componentModel = "spring",
        unmappedTargetPolicy = ReportingPolicy.IGNORE,
        unmappedSourcePolicy = ReportingPolicy.IGNORE,
        nullValuePropertyMappingStrategy = NullValuePropertyMappingStrategy.IGNORE)
public interface ProblemAssembler {
    ProblemAssembler Instance = Mappers.getMapper(ProblemAssembler.class);

    // region problem
    @Mapping(target = "questions", expression = "java(ProblemAssemblyLoader.toQuestionVOs(entity.getCurrentQuestions()))")
    @Mapping(target = "stem", expression = "java(ProblemAssemblyLoader.toStemVO(entity.getCurrentStem()))")
    ProblemVO toProblemVO(Problem entity);
    // endregion


    // region stem
    StemVO toStemVO(Stem entity);
    // endregion

    // region question
    @Mapping(target = "answers", expression = "java(ProblemAssemblyLoader.toAnswerVOs(entity.getCurrentAnswers()))")
    @Mapping(target = "options", expression = "java(ProblemAssemblyLoader.toOptionVOs(entity.getCurrentOptions()))")
    QuestionVO toQuestionVO(Question entity);
    // endregion

    // region option
    OptionVO toOptionVO(Option entity);
    // endregion

    // region answer
    AnswerVO toAnswerVO(Answer entity);
    // endregion

    // region solution
    SolutionVO toSolutionVO(Solution entity);
    // endregion


    // region simple problem
    CreateSimpleProblemCommand toCreateSimpleProblemCommand(CreateProblemCommand command);

    UpdateSimpleProblemCommand toUpdateSimpleProblemCommand(UpdateProblemCommand command);

    // endregion

    // region composite problem
    CreateCompositeProblemCommand toCreateCompositeProblemCommand(CreateProblemCommand command);

    UpdateCompositeProblemCommand toUpdateCompositeProblemCommand(UpdateProblemCommand command);
    // endregion

    // region hybrid problem
    CreateHybridProblemCommand toCreateHybridProblemCommand(CreateProblemCommand command);

    UpdateHybridProblemCommand toUpdateHybridProblemCommand(UpdateProblemCommand command);
    // endregion

    // region knowledge point
    ProblemKnowledgePointVO toProblemKnowledgePointVO(ProblemKnowledgePoint point);

    ProblemKnowledgePoint toNonPrimaryProblemKnowledgePoint(KnowledgePointVO vo);

    ProblemKnowledgePointVO toProblemKnowledgePoint(KnowledgePointVO vo);
    // endregion

    // region tag
    TagName toTagName(TagVO vo);

    TagName toTagName(TagNameVO vo);

    com.wiscamp.ninechapters.problems.application.dto.vo.problems.TagNameVO toTagNameVO(TagName entity);
    // endregion

}
